-- SelfDestructM
-- created by panyl
-- 自动销毁装备

module("SelfDestructM", package.seeall);

local whenDoEquip;
local whenDoUnequip;
local whenEnterNextFloor;

local equips = {};

local rules = {};

-- 载入配置表
local _init = false;
local loadCsv = function()
    if _init then return end
    _init = true;

    -- 转换下self_destruct信息表
    local self_destruct_CSV = get_self_destruct_CSV();
    for i = 1, #self_destruct_CSV do
        equips[self_destruct_CSV[i].class_id] = self_destruct_CSV[i];
    end

    self_destruct_CSV = {};
end

function init()
    if not _init then
        loadCsv();

        -- 载入所有的规则处理子模块
        rules = LOAD_PATH("game/logic/module/self_destruct");
    end

    -- 关注玩家离开地牢的事件
    EventMgr.removeAll("SelfDestructM");
    EventMgr.register("SelfDestructM", event.LEAVE_DUNGEON, function()
        ME.user.dbase:delete("self_destruct");
    end);

    -- 关注玩家穿装备事件
    EventMgr.register("SelfDestructM", event.EQUIP, whenDoEquip);

    -- 关注玩家卸下装备事件
    EventMgr.register("SelfDestructM", event.UNEQUIP, whenDoUnequip);

    -- 关注玩家进入下一层事件
    EventMgr.register("SelfDestructM", event.START_DUNGEON, whenEnterNextFloor)
end

-- 检索
function query(classId, path)
    local m = equips[classId];

    if not m or not path then
        return m;
    end

    return m[path];
end

-- 自动销毁装备描述后缀
function SelfDestructDesc(classId, isEquiped)
    if not classId or not EquipM.isEquipment(classId) then
        return "";
    end

    local info = query(classId);
    if not info then
        return "";
    end

    -- 暂时只有按层算的
    local layer = info["last"];
    if not layer then
        return "";
    end

    local ret = info.desc;

    -- 如果是未装备的
    if not isEquiped then
        ret = string.gsub(ret, "{left}", 0);
    else
        -- 已经装备了，从身上取数据
        local curr = ME.user.dbase:query("self_destruct", {});
        local equipType = EquipM.query(classId, "type");

        if type(curr[equipType]) ~= "table" or curr[equipType].class_id ~= classId then
            ret = "";
        else
            local left = DungeonM.currentLayer() - curr[equipType].layer;
            ret = string.gsub(ret, "{left}", left);
        end
    end

    local rule = query(classId, "rule");
    local mod = rules[rule];
    if mod and mod.suffixDesc then
        -- 需要加上后缀
        local suffix = mod.suffixDesc(classId);
        if #suffix > 0 then
            ret = ret .. "\n" .. suffix;
        end
    end

    return ret;
end

-- 自动销毁之后得到的效果
function applyEffect(classId)
    local rule = query(classId, "rule");
    local mod = rules[rule];
    if mod and mod.applyEffect and mod.applyEffect(classId) then
        -- 子模块处理掉了
        EventMgr.fire(event.SELF_DESTRUCT_EFFECT, classId);

        return;
    end

    local effect = query(classId, "effect");
    if not effect then
        return;
    end

    local bonusList = {};
    -- 遍历
    for key, value in pairs(effect) do
        if key == "bonus" then
            -- 奖励
            for _, bonus in pairs(value) do
                BonusM.doBonus(bonus, "self_desturct_" .. classId);
                table.insert(bonusList, bonus);
            end
        end
    end
    
    if #bonusList > 0 then
        local destructEquip = ME.user.destructEquip or {};
        table.insert(destructEquip, {["classId"] = classId, ["bonusList"] = bonusList, ["notifyType"] = "form"});
        ME.user.destructEquip = destructEquip;
    end

    -- TODO: 抛出事件
    EventMgr.fire(event.SELF_DESTRUCT_EFFECT, classId);
end

-- 是否自销毁装备
function isSelfDestructEquipment(classId)
    if not equips[classId] then
        return false;
    end

    return true;
end

-- 穿装备回调
whenDoEquip = function(classId)
    -- 如果不是在地牢中
    if not DungeonM.isInDungeon() then
        return;
    end

    if not query(classId) then
        -- 不是自动销毁装备
        return;
    end

    local equipType = EquipM.query(classId, "type");
    local data = ME.user.dbase:query("self_destruct", {});
    data[equipType] = {
        ["class_id"] = classId,
        ["layer"]    = DungeonM.currentLayer(),
    };

    ME.user.dbase:set("self_destruct", data);
end

-- 卸下装备回调
whenDoUnequip = function(para)
    -- 如果不是在地牢中
    if not DungeonM.isInDungeon() then
        return;
    end

    if not query(classId) then
        -- 不是自动销毁装备
        return;
    end

    local classId = para["classId"];
    local equipType = EquipM.query(classId, "type");
    local data = ME.user.dbase:query("self_destruct", {});

    if not data[equipType] or data[equipType].class_id ~= classId then
        return;
    end

    data[equipType] = nil;

    ME.user.dbase:set("self_destruct", data);
end

-- 进入下一层回调
whenEnterNextFloor = function()
    local currLayer = DungeonM.currentLayer();
    local list = ME.user.dbase:query("self_destruct");

    local equipments = ME.user.equipments;

    if not list or not equipments then
        return;
    end

    -- 遍历所有的自动销毁装备，如果已经到期了，直接销毁
    for _, equipType in pairs(table.keys(list)) do
        repeat
            local data = list[equipType];
            if not data.class_id then
                break;
            end
            local classId = data.class_id;

            -- 未到期
            if data.layer + query(classId, "last") > currLayer then
                break;
            end

            -- 先清除
            list[equipType] = nil;

            -- 当前未装备该类型的装备
            if not equipments[equipType] or table.indexOf(equipments[equipType], classId) <= 0 then
                break;
            end

            -- 装备直接干掉
            equipments[equipType] = nil;

            -- 效果
            applyEffect(classId);

        until true;
    end

    ME.user.dbase:set("self_destruct", list);
    ME.user.equipments = equipments;

    -- 刷新下属性
    PropM.refresh(ME.user);
end
